From dd7c8c5aef8d00d6bc6c93e5678e497b8af0dd5e Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 13 Nov 2007 19:05:27 +0000 Subject: [PATCH] vmx: Restore correct host SYSENTER parameters on vmexit. Also simplify vmx_set_host_env(). HOST_GDT_BASE does not have to change when we shift CPU. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/vmx/vmcs.c | 33 +++++++++++++++++------------- xen/include/asm-x86/hvm/vmx/vmcs.h | 6 +++--- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 2a84b38a34..14d54496ba 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -399,21 +399,15 @@ struct xgt_desc { static void vmx_set_host_env(struct vcpu *v) { - unsigned int tr, cpu; - struct xgt_desc desc; + unsigned int cpu = smp_processor_id(); - cpu = smp_processor_id(); + __vmwrite(HOST_IDTR_BASE, (unsigned long)idt_tables[cpu]); - __asm__ __volatile__ ( "sidt (%0) \n" : : "a" (&desc) : "memory" ); - __vmwrite(HOST_IDTR_BASE, desc.address); - - __asm__ __volatile__ ( "sgdt (%0) \n" : : "a" (&desc) : "memory" ); - __vmwrite(HOST_GDTR_BASE, desc.address); - - __asm__ __volatile__ ( "str (%0) \n" : : "a" (&tr) : "memory" ); - __vmwrite(HOST_TR_SELECTOR, tr); + __vmwrite(HOST_TR_SELECTOR, __TSS(cpu) << 3); __vmwrite(HOST_TR_BASE, (unsigned long)&init_tss[cpu]); + __vmwrite(HOST_SYSENTER_ESP, get_stack_bottom()); + /* * Skip end of cpu_user_regs when entering the hypervisor because the * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc @@ -454,6 +448,8 @@ void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr) static int construct_vmcs(struct vcpu *v) { union vmcs_arbytes arbytes; + uint16_t sysenter_cs; + unsigned long sysenter_eip; vmx_vmcs_enter(v); @@ -489,6 +485,9 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(IO_BITMAP_A, virt_to_maddr(hvm_io_bitmap)); __vmwrite(IO_BITMAP_B, virt_to_maddr(hvm_io_bitmap + PAGE_SIZE)); + /* Host GDTR base. */ + __vmwrite(HOST_GDTR_BASE, GDT_VIRT_START(v)); + /* Host data selectors. */ __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS); __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS); @@ -506,6 +505,12 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS); __vmwrite(HOST_RIP, (unsigned long)vmx_asm_vmexit_handler); + /* Host SYSENTER CS:RIP. */ + rdmsrl(MSR_IA32_SYSENTER_CS, sysenter_cs); + __vmwrite(HOST_SYSENTER_CS, sysenter_cs); + rdmsrl(MSR_IA32_SYSENTER_EIP, sysenter_eip); + __vmwrite(HOST_SYSENTER_EIP, sysenter_eip); + /* MSR intercepts. */ __vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0); __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0); @@ -903,9 +908,9 @@ void vmcs_dump_vcpu(void) (unsigned long long)vmr(HOST_CR3), (unsigned long long)vmr(HOST_CR4)); printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n", - (unsigned long long)vmr(HOST_IA32_SYSENTER_ESP), - (int)vmr(HOST_IA32_SYSENTER_CS), - (unsigned long long)vmr(HOST_IA32_SYSENTER_EIP)); + (unsigned long long)vmr(HOST_SYSENTER_ESP), + (int)vmr(HOST_SYSENTER_CS), + (unsigned long long)vmr(HOST_SYSENTER_EIP)); printk("*** Control State ***\n"); printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n", diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index 132aa1d529..d3da4e3549 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -235,7 +235,7 @@ enum vmcs_field { GUEST_INTERRUPTIBILITY_INFO = 0x00004824, GUEST_ACTIVITY_STATE = 0x00004826, GUEST_SYSENTER_CS = 0x0000482A, - HOST_IA32_SYSENTER_CS = 0x00004c00, + HOST_SYSENTER_CS = 0x00004c00, CR0_GUEST_HOST_MASK = 0x00006000, CR4_GUEST_HOST_MASK = 0x00006002, CR0_READ_SHADOW = 0x00006004, @@ -274,8 +274,8 @@ enum vmcs_field { HOST_TR_BASE = 0x00006c0a, HOST_GDTR_BASE = 0x00006c0c, HOST_IDTR_BASE = 0x00006c0e, - HOST_IA32_SYSENTER_ESP = 0x00006c10, - HOST_IA32_SYSENTER_EIP = 0x00006c12, + HOST_SYSENTER_ESP = 0x00006c10, + HOST_SYSENTER_EIP = 0x00006c12, HOST_RSP = 0x00006c14, HOST_RIP = 0x00006c16, }; -- 2.30.2